#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

struct sembuf up = {0, 1, 0};

struct sembuf down = {0, -1, 0};


void mutex_lock(int semaphore_id)
{
  if (semop(semaphore_id, &down, 1) < 0) {
    printf("Error locking semaphore");
    exit(1);
  }
}

void mutex_unlock(int semaphore_id)
{
  if (semop(semaphore_id, &up, 1) < 0) {
    printf("Error unlocking semaphore");
    exit(1);
  }
}

int mutex_create()
{
  int semaphore_id = semget(IPC_PRIVATE, 1, 0600);
  if (semaphore_id < 0) {
    printf("Error creating semaphore");
    exit(1);
  }
  mutex_unlock(semaphore_id); 
  return semaphore_id;
}


void mutex_destroy(int semaphore_id) 
{
  if (semctl(semaphore_id, 0, IPC_RMID) < 0) {
    printf("Error deleting semaphore");
    exit(1);
  }
}

void display(char *str) 
{
  char *tmp;
  for (tmp=str;*tmp;tmp++) {
    write(1,tmp,1);
    usleep(100);
  }
}

int main() 
{
  int i;
  int mutex_semaphore = mutex_create();
  if (fork()) {
    for (i=0;i<10;i++) {
      mutex_lock(mutex_semaphore);
      display("Hello world\n");
      mutex_unlock(mutex_semaphore);
    }
    wait(NULL);
    mutex_destroy(mutex_semaphore);
  }
  else {
    for (i=0;i<10;i++) {
      mutex_lock(mutex_semaphore);
      display("Bonjour monde\n");
      mutex_unlock(mutex_semaphore);
    }
  }

  return 0;
}

